/*
 * Main program with interrupt vectors, timers, and audio code, and IR function
 *
 *
 *      Author: Ian
 *
 * Functions by: Robert Elliott
 */

#include "msp430f5172.h"
#include <msp430.h>
#include <stdio.h>
#include "max7221.h"
#include "uart.h"
#include "configbits.h"

//Timer and Interrupt flags and counters
volatile unsigned char count;							// counter for Timer 1.1 seconds
volatile unsigned int shot;								// high if system has been shot
volatile unsigned char TEST = 0;
volatile unsigned int health;							// total health
volatile unsigned char x;									// Unsigned mode bit
volatile unsigned int packet_length = 11;
volatile unsigned int bits;
volatile unsigned char badIR;							// Checks to see if shot or not

void countdownSequence(void);
void audioSequence(char address);
void Xbee(char *data);
void ledSequence(char kittystorm);
void Detonation(char maybebaby);
void igotShot(void);
void spiOut(char);

//------------------------------------------------------------------------------
// Function prototypes

void init(void);
void irRead(char shot);

//-------------------------------------------------------------------------------
// Packet defines
char DAMAGE_TX [] = {0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01};
char DAMAGE_RX [] = {0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00};
char HEALING_TX [] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00};
char HEALING_RX [] = {0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01};
//char REMOTE_TX [] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00};
char REMOTE_RX [] = {0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01};

//-------------------------------------------------------------------------------


void main(void)
{
// Flags and Counters
	 health = 4;								// Total health of the crystal
	 count = 0;									// Counter for reading in signal for MIRP
	 shot = 0;									// Flag for IR weapon hit
	 badIR = 0;
//----------------------------------------------------------------------------------------
	init();								// Initialize bits and stuff
	maxInit();						// initialize max7221
	Uart_init();					// initialize uart
	//__enable_interrupt();
	__bis_SR_register(GIE);
	while(1)
	{
		print("In main loop\r\n");	//Debugging
		if(shot == 1)
		{
			igotShot();
		}
		if((P3IN & BIT3) == BIT3) 				// Damage if analog High
		  x = 1; 								// Damage
		else
		  x = 2; 								// Healing
			if((P3IN & BIT2) == BIT2) 			// Timer if analog High, Remote if analog Low
			{
			countdownSequence();
			Detonation(x);
			}
			if((P3IN & BIT1) == BIT1){	 		// Remote, keep polling. ***Change this so no interrupts until timer pressed
				P1IE &= ~BIT0;					// Disable interrupts
				while(!((P3IN & BIT2) == BIT2))	//Polls until timer pressed
				{
					if(!((P3IN & BIT5) == BIT5))
					irRead(2);	//don't forget to send a status parameter
					Detonation(x);
				}
				break;
			}
			else;
	  }
}

void countdownSequence(void)					// Fix for LED display
{
	volatile unsigned int x;
	audioSequence(1);
	print("It's the final count down!!!\r\n");
	if(shot == 1)
	{
		igotShot();
	}
	//ledSequence(countdown);
	__delay_cycles(900000);
	print("You gonna die!!!\r\n");
	for(x=4;x>0;x--)
	{
	if(shot == 1)
	{
		igotShot();
	}
	P1OUT ^= BIT6;
	__delay_cycles(900000);
	}
}

void audioSequence(char address) 	// Fix Switches
{
	switch( address )
	 {
	   case 1: P1OUT &= ~BIT7; 		// MSB BIT 1 Low (Direct Mode, address 001 for timer)
	   print("Count down song!\r\n");
	   	   	   break;
	   case 2: P2OUT &= ~BIT0;		// MSB 1 (Direct Mode, address 010 for damage)
	   print("Damage song!\r\n");
		   	   break;
	   case 3: P2OUT &= ~BIT1; 		// MSB 1 (Direct Mode, address 011 for healing)
	   print("Healing song!\r\n");e
			break;
	   case 4: P2OUT &= ~BIT2; 		// MSB 1 (Dirt Mode, address 100 for hit)
	   print("I got shot song!\r\n");
	   		   break;
		 }
		__delay_cycles(33000);
		P1OUT = BIT7;
		P2OUT = BIT0 + BIT1 + BIT2; // Set back high

	}
void ledSequence(char kittystorm) 			// Fix Distoo
{
	if(shot == 1)
	{
		igotShot();
	}
}

// This function is long 
void irEmission(char mode) 					// TA_CLK set and use with perifs.
{
	int i;
	int irSequence = 0; // Long, Med, then short IR sequence

	while(irSequence < 3){
	for(i = 0; i<= packet_length; i++)
	{
		bits = 0;
		if((mode == 1) && DAMAGE_TX [i] == 0x01)
		{
			while(bits < 3)
			{
				if(irSequence == 0)
				{
					P2SEL |= BIT7;							//Long IR
					P2SEL &= ~BIT6 + ~BIT5;					//Turn off Medium and Short
				}
				else if(irSequence ==1)
				{
					P2SEL |= BIT6;							//Med IR
					P2SEL &= ~BIT5 + ~BIT7;					//Turn off Long and Short
				}
				else
				{
					P2SEL |= BIT5;							//Short IR
					P2SEL &= ~BIT5 + ~BIT7;					//Turn off Long and Medium IR
				}

				__delay_cycles(555);					//Delay for 1.1ms
				bits++;									//bits counter for 3.3ms
			}
		}

		else if((mode == 1) && DAMAGE_TX [i] == 0x00)
		{
			while(bits < 3)
			{
				if(irSequence == 0)
					P2SEL &= ~BIT7;							//Turn off Long IR
				else if(irSequence == 1)
					P2SEL &= ~BIT6;							//Turn off Medium IR
				else
					P2SEL &= ~BIT5;							//Turn off Short IR

				__delay_cycles(555);
				bits++;
			}
		}
		else if((mode == 2) && HEALING_TX[i] == 0x01)
		{
			while(bits < 3)
			{
				if(irSequence == 0)
				{
					P2SEL |= BIT7;							//Long IR
					P2SEL &= ~BIT6 + ~BIT5;					//Turn off Medium and Short
				}
				else if(irSequence ==1)
				{
					P2SEL |= BIT6;							//Med IR
					P2SEL &= ~BIT5 + ~BIT7;					//Turn off Long and Short
				}
				else
				{
					P2SEL |= BIT5;							//Short IR
					P2SEL &= ~BIT5 + ~BIT7;					//Turn off Long and Medium IR
				}e
				__delay_cycles(555);					//Delay for 1.1ms
				bits++;									//bits counter for 3.3ms
				}
			}
		  else if((mode == 2) && HEALING_TX[i] == 0x00)
		  {
				while(bits < 3)
				{
					if(irSequence == 0)
		  	 		P2SEL &= ~BIT7;							//Turn off Long IR
		   		else if(irSequence == 1)
		  	 		P2SEL &= ~BIT6;							//Turn off Medium IR
		   		else
		    		P2SEL &= ~BIT5;							//Turn off Short IR
  					__delay_cycles(555);
   					bits++;
  			}
			}
		   else;
		}
		irSequence ++;
		__delay_cycles(5555);
	}
}

void Detonation(char maybebaby)				// Fix Dis
{
	if(shot == 1)							// Poll to see if interrupt vector signal is high
	{
		igotShot();
	}
	print("BOOM DETONATED!\r\n");
	//__delay_cycles(90000);
	if((P1IN & BIT7) == BIT7) 				// Damage if analog High
		x = 1; 						// Damage
	else	
		x = 2;						// Healing
		audioSequence(x);
		ledSequence(x);
		irEmission(x);
		Detonation(x);			// changed code don't need x
		count = 0;
	// if((P2IN & BIT5) == BIT5)	 // Remote, keep polling. Until change or interrupt
	//
}

void igotShot(void)
{
	//Check for valid shot MIRP(); protocol
	irRead(1);
	if(badIR == 0)
	{
	volatile unsigned char x;
	print("I GOT SHOHT!\r\n");
	x = 4; // Hit Display
	//__delay_cycles(90000);
	//P1OUT ^= BIT0;

	//__delay_cycles(90000);	So tired

	//P1OUT ^= BIT6;
	audioSequence(x);
	ledSequence(x);
	Xbee("send");
	shot = 0;				// reset shot
	}

	badIR = 0;
}

void irRead(char shot)		// Read in MIRP packet
{
	P1IE &= ~BIT0;			// Disable Interrupts during read in

	int i;
	char packet_bit;
	for(i = 0; i<= packet_length; i++)	// while i is less than 11
	{
		bits = 0;
		packet_bit = 0;		// bit counter for pwm signal
		while(bits < 3)
		{
			if((P1IN & BIT0) == BIT0)
			packet_bit++;
			__delay_cycles(555);					//Delay for 1.1ms
			bits++;									//bits counter for 3.3ms
		}
		if(shot == 1)								// Weapon shot
		{
			packet_bit = packet_bit % 3;
			if(packet_bit > 1)						// If greater than 1 then receiver sending low
				packet_bit = 0x00;
			else
				packet_bit = 0x01;
		if(!(packet_bit == DAMAGE_RX[i]))
		{
			badIR = 1;
			print("Bad IR shot");
			P1IE |= BIT0;
			P1IFG &= ~BIT0;
			break;
		}
		bits = 0;
	}

		if(shot == 2)								// Remote shot
		{
			packet_bit = packet_bit % 3;
			if(packet_bit > 1)						// If greater than 1 then receiver sending low
			packet_bit = 0x00;
			else
			packet_bit = 0x01;
		if(!(packet_bit == HEALING_RX[i]))
		{
			badIR = 1;
			print("Bad IR shot");
			P1IE |= BIT0;
			P1IFG &= ~BIT0;
			break;
		}
			bits = 0;
		}
	}

	P1IE |= BIT0;
	P1IFG &= ~BIT0;
}

// Port 1 interrupt service routine for timer sequence
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
	if((P1IFG && BIT0) == BIT0)
	{
		//P1OUT ^= BIT6;		//TESTing
		//P1OUT ^= BIT0;		//TESTing
		P2SEL &= ~BIT5 + ~BIT6 + ~BIT7;	//turn off pwm
		P1IFG &= ~BIT0;
		shot = 1;
	}
}
